package pure.engine.model 
{
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import pure.debug.Logger;
	import pure.engine.core.ProcessManager;
	import pure.engine.core.ITickListener;
	import pure.engine.model.sections.Action;
	import pure.engine.model.sections.Section;
	import pure.engine.model.sections.SectionManager;
	import pure.engine.core.ns_despair;
		
	use namespace ns_despair;
	
	/**
	 * 动画渲染器
	 * [Author] - PURE
	 * 
	 */
public class AnimeRenderer extends Renderer implements IAnime, ITickListener
{

	
	
	//======================
	// Const
	//======================
	
	
	ns_despair static const a_playFlag:uint    =  0x01;  // 播放
	ns_despair static const a_repeatFlag:uint  =  0x02;  // 重复
	
	ns_despair static const a_tickFlag:uint    =  0x10;  // 正在Tick，不可见或非渲染时，一定为false
	
	
	
	
	//======================
	// Property
	//======================
	
	
	/**
	 * 设置片段
	 */
	public function set section(v:String):void
	{
		if (m_sectionName != v)
		{
			setSection(v);
			if (m_animeFlags & a_tickFlag == a_tickFlag)
			{
				ProcessManager.instance.removeTickListener(this);
			}
			this._setRendererFlag(r_dirtyRangeFlag);
			
			m_pointer     =  1;
			m_animeFlags  =  0;
		}
	}
	
	
	/**
	 * 设置指针
	 */
	public function set pointer(v:int):void
	{
		if (m_pointer != v)
		{
			if (m_animeFlags & a_tickFlag == a_tickFlag)
			{
				ProcessManager.instance.removeTickListener(this);
			}
			this._setRendererFlag(r_dirtyImageFlag);
			
			m_pointer     =  v;
			m_animeFlags  =  0;
		}
	}
	
	
	/**
	 * 是否可见
	 */
	override public function set visible(b:Boolean):void
	{ 
		super.visible = b;
		if (b)
		{
			resume();
		}
		else
		{
			pause();
		}
	}
	

	
	
	//======================
	// Base
	//======================
	
	
	/**
	 * 播放
	 * 
	 * [Param] - action    动作
	 * [Param] - section   片段
	 * [Param] - repeated  是否重复
	 */
	public function play(action:String, section:String = null, repeated:Boolean = false):void
	{
		if (_checkSection(section))
		{
			_setRendererFlag(r_dirtyRangeFlag);
			_playAction(action, 0, 0, repeated);
		}
		else
		{
			_playAction(action, 0, 0, repeated)
			_setRendererFlag(r_dirtyImageFlag);
		}
	}
	
	
	/**
	 * 计时播放
	 * 
	 * [Param] - action    动作
	 * [Param] - duration  持续时间
	 * [Param] - section   片段
	 * [Param] - repeated  是否重复
	 */
	public function tick(action:String, duration:Number, section:String = null, repeated:Boolean = false):void
	{
		if (_checkSection(section))
		{
			_setRendererFlag(r_dirtyRangeFlag);
			_playAction(action, 0, duration, repeated);
		}
		else
		{
			_playAction(action, 0, duration, repeated);
			_setRendererFlag(r_dirtyImageFlag);
		}
	}
	

	/**
	 * 获取持续时间
	 * 
	 * [Param] - actions  动作名字列表
	 */
	public function getDuration(...actions):Number
	{
		var duration:Number = 0;
		var A:Action;
		var l:int = actions.length;
		
		while (--l > -1)
		{
			A = m_section.getActionByName(actions[l]);
			if (!A)
			{
				Logger.reportError(this, 'getDuration', '片段<' + m_section.m_name +'>，不存在的动作<' + actions[l] +'>...');
			}
			duration += ((A.delay / m_animeSpeed + 0.5) >> 0) * A.group.length * 0.001;
		}
		return duration;
	}
	

	/**
	 * 暂停
	 */
	public function pause():void
	{
		if (Boolean(m_animeFlags & a_tickFlag))
		{
			ProcessManager.instance.removeTickListener(this);
			m_animeFlags &= ~a_tickFlag;
		}
	}
	
	
	/**
	 * 恢复
	 */
	public function resume():void
	{
		if (Boolean(m_animeFlags & 0x0F) && !Boolean(m_animeFlags & a_tickFlag) && !Boolean(m_flags & 0xF0))
		{
			ProcessManager.instance.addTickListener(this, ProcessManager.ANIME);
			m_animeFlags |= a_tickFlag;
		}
	}

	
	/**
	 * 重置
	 * 
	 * [Param] - autoPlay  是否自动播放
	 * 
	 * [Hint] - 回到当前动作起点
	 */
	public function reset(autoPlay:Boolean = true):void
	{
		cachedGroupIndex = 0;
		if (!Boolean(m_flags & 0xF0))
		{
			if (autoPlay)
			{
				if (Boolean(m_animeFlags & 0x0F) && !Boolean(m_animeFlags & a_tickFlag))
				{
					ProcessManager.instance.addTickListener(this, ProcessManager.ANIME);
					m_animeFlags |= a_tickFlag;
				}
				cachedTime = 0;
			}
			else
			{
				if (Boolean(m_animeFlags & a_tickFlag))
				{
					ProcessManager.instance.removeTickListener(this);
					m_animeFlags &= ~a_tickFlag;
				}
			}
			this._setRendererFlag(r_dirtyImageFlag);
		}
	}
	


	/**
	 * 进程处理
	 */
	public function update(deltaTime:Number):void 
	{
		if ((cachedTime += deltaTime) >= cachedDelay)
		{
			if (++cachedGroupIndex >= cachedLength) 
			{	
				if (Boolean(m_animeFlags & a_repeatFlag))
				{
					cachedGroupIndex = 0;
				}
				else
				{
					ProcessManager.instance.removeTickListener(this);
					m_animeFlags = 0;
					return;
				}
			}		
			
			var pointer:int = m_group[cachedGroupIndex];
			
			if (pointer != m_pointer)
			{
				m_pointer = pointer;
				this._setRendererFlag(r_dirtyImageFlag);
			}
			cachedTime -=  cachedDelay;	
		}
	}
	
	
	/**
	 * 设置片段
	 * 
	 * [Param] - section  片段名字
	 */
	ns_despair function setSection(section:String):void 
	{
		m_section  =  SectionManager.getSection(m_sectionName = section);
		m_x        =  m_section.m_x;
		m_y        =  m_section.m_y;
	}
	
	
	/**
	 * 开启渲染
	 */
	override ns_despair function enable():void
	{
		super.enable();
		resume()
	}
	
	
	/**
	 * 阻止渲染
	 */
	override ns_despair function disable():void
	{
		super.disable();
		pause();
	}
	
	
	
	
	/* ----------------------------------------------------------------------------------------------------------------
	 * ★★★★★★★★★★★★★★★★★★★★★  private  ★★★★★★★★★★★★★★★★★★★★★
	 * ----------------------------------------------------------------------------------------------------------------
	 */

	


	/**
	 * 播放动作
	 * 
	 * [Param] - actionName  动作名字
	 * [Param] - index       当前索引
	 * [Param] - duration    手动持续时间(毫秒)
	 * [Param] - repeated    是否重复
	 * 
	 * [Feature] - ① 帧1-2-3-4...由最初帧到最后帧，改变次数为 numFrame
	 */
	ns_despair function _playAction(actionName:String, index:int, duration:int, repeated:Boolean):void 
	{
		var A:Action = m_section.getActionByName(actionName);
		
		if (!A)
		{
			Logger.reportError(this, '_playAction', '片段<' + m_section.m_name +'>，不存在的动作<' + actionName +'>...');
		}
		
		m_group           =  A.group;
		cachedLength      =  m_group.length;
		cachedGroupIndex  =  index;
		m_pointer         =  m_group[index];
		
		if (cachedLength == 1) 
		{
			if (Boolean(m_animeFlags & a_tickFlag))
			{
				ProcessManager.instance.removeTickListener(this);
			}
			m_animeFlags = 0;
		}
		else
		{
			m_animeFlags  =  repeated ? (a_playFlag | a_repeatFlag) : a_playFlag;
			cachedDelay   =  Boolean(duration <= 0) ? A.delay / m_animeSpeed : duration / cachedLength;
			cachedTime    =  0;
			
			if(!Boolean(m_animeFlags & a_tickFlag) && !Boolean(m_flags & (r_invisibleFlag | r_noRenderFlag)))
			{
				ProcessManager.instance.addTickListener(this, ProcessManager.ANIME);
				m_animeFlags |= a_tickFlag;
			}
		}
	}
	
	
	/**
	 * 检查片段是否变化
	 */
	ns_despair function _checkSection(section:String):Boolean
	{
		if (section != null && m_sectionName != section)
		{
			m_section  =  SectionManager.getSection(m_sectionName = section);
			m_x        =  m_section.m_x;
			m_y        =  m_section.m_y;
			return true;
		}
		return false;
	}
	
	
	/**
	 * [Overwrite]
	 * 
	 * 画像
	 */
	override ns_despair function _generatePrimaryImage():BitmapData 
	{
		return m_section.getBitmapByPointer(m_pointer);
	}
	
	
	/**
	 * [Overwrite]
	 * 
	 * 毁灭
	 */
	override ns_despair function destroy():void
	{
		if (m_animeFlags & a_tickFlag)
		{
			ProcessManager.instance.removeTickListener(this);
		}
		m_section     =  null;
		m_group       =  null;
		//m_animeFlags  =  0;
		
		super.destroy();
	}
	

	
	
	
	
	//======================
	// Member
	//======================

	
	ns_despair static var m_animeSpeed:Number;  // 总动画速率
	
	
	ns_despair var m_section:Section;  // 片段加入后，初期化设置或

	ns_despair var m_group:Vector.<int>;  // 当前组

	ns_despair var m_sectionName:String;  // 片段名字

	ns_despair var m_animeFlags:int;  // 动画状态
	
	ns_despair var m_pointer:int = 1;
	
	ns_despair var cachedGroupIndex:int;
	
	ns_despair var cachedLength:int;
	
	ns_despair var cachedTime:int;
	
	ns_despair var cachedDelay:Number;
	
}
}